/******************************************************************************\
    WindowClass.hpp contains a class of windows window class.
    Copyright (C) 2008  Victor Vinogradov (fly3333@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
\******************************************************************************/

#ifndef __WINDOW_CLASS_HPP
#define __WINDOW_CLASS_HPP

#include <windows.h>
#include ".\Object.hpp"

class cSubWindowClass : public cSubObject
{
	ATOM Atom;
	HINSTANCE Instance;
public:
	cSubWindowClass( ATOM atom, HINSTANCE instance )
		: Atom( atom )
		, Instance( instance )
	{
	}
	~cSubWindowClass()
	{
		UnregisterClass( MAKEINTRESOURCE( Atom ), Instance );
	}
	ATOM GetAtom() const 
	{
		return Atom;
	}
	HINSTANCE GetInstance() const
	{
		return Instance;
	}
};

class cWindowClass : public cObject< cSubWindowClass >
{
public:
	bool Register( CONST WNDCLASSEX *lpwcx )
	{
		ATOM atom = RegisterClassEx( lpwcx );
		if( atom == 0 )
			return false;
		cSubWindowClass *sub_window_class;
		try
		{
			sub_window_class = new cSubWindowClass( atom, lpwcx->hInstance );
		}
		catch( ... )
		{
			return false;
		}
		SwitchToSubObject( sub_window_class );
		return true;
	}
	void Unregister()
	{
		SwitchToSubObject( NULL );
	}
	operator ATOM() const
	{
		if( GetSubObject() == NULL )
			return 0;
		return GetSubObject()->GetAtom();
	}
	bool GetInfo( LPWNDCLASSEX window_class )
	{
		if( GetSubObject() == NULL )
			return false;
		return ::GetClassInfoEx( GetSubObject()->GetInstance(), MAKEINTRESOURCE( GetSubObject()->GetAtom() ), window_class ) != FALSE;
	}
};

struct sWindowClass : public WNDCLASSEX
{
	sWindowClass()
	{
		memset( this, 0, sizeof( *this ) );
		cbSize = sizeof( WNDCLASSEX );
	}
	sWindowClass( UINT style, WNDPROC window_procedure, int class_extra_memory, int window_extra_memory, HINSTANCE instance, HICON icon, HCURSOR cursor, HBRUSH background, LPCTSTR menu_name, LPCTSTR class_name, HICON small_icon )
	{
		cbSize = sizeof( WNDCLASSEX );
		this->style = style;
		lpfnWndProc = window_procedure;
		cbClsExtra = class_extra_memory;
		cbWndExtra = window_extra_memory;
		hInstance = instance;
		hIcon = icon;
		hCursor = cursor;
		hbrBackground = background;
		lpszMenuName = menu_name;
		lpszClassName = class_name;
		hIconSm = small_icon;
	}
};

#endif
